﻿using MyUi_WPF_Controls.ComBoxCtr;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace MyUi_WPF_Controls.AnimLogoFontctr
{
    /// <summary>
    /// AnimLogoFontCtr.xaml 的交互逻辑
    /// </summary>
    public partial class AnimLogoFontCtr : UserControl
    {
        const string NAME_TRANSFORM = "TextGradientTranslateTransform";
        // 颜色渐变动画时长
        const int TIME_FOREGROUND_TRANSFORM = 2;


        double mWidth, mHeight;
        private char[] LogoTexts;
        private List<FormattedText> LogoTextFormatteds = new List<FormattedText>();
        private List<Point> aimLocationPoints = new List<Point>();
        private List<Point> randomLocationPoints = new List<Point>();

        bool isMoving = false;



        public static readonly DependencyProperty ContenTextProperty = DependencyProperty.Register("ContenText"
            , typeof(string), typeof(AnimLogoFontCtr),new PropertyMetadata("蕴硕物联"));
        /// <summary>
        /// 文本
        /// </summary>
        public string ContenText
        {
            get { return (string)GetValue(ContenTextProperty); }
            set { SetValue(ContenTextProperty, value); }
        }

        public static readonly DependencyProperty ContenForegroundProperty = DependencyProperty.Register("ContenForeground"
        , typeof(Brush), typeof(AnimLogoFontCtr),new PropertyMetadata(Brushes.Black));
        /// <summary>
        /// 
        /// </summary>
        public Brush ContenForeground
        {
            get { return (Brush)GetValue(ContenForegroundProperty); }
            set { SetValue(ContenForegroundProperty, value); }
        }

        public AnimLogoFontCtr()
        {
            InitializeComponent();

            SplitLogoTextArray(ContenText);
            InitLinearBrush();
        }

        private void SplitLogoTextArray(string logoText)
        {
            if (string.IsNullOrEmpty(logoText))
                MessageBox.Show("logoText == null");
            LogoTexts = logoText.ToCharArray();

            foreach (var item in LogoTexts)
            {
                LogoTextFormatteds.Add(new FormattedText(item.ToString(),
                        CultureInfo.InvariantCulture,
                        FlowDirection.LeftToRight,
                        new Typeface(LogoTextTb.FontFamily.ToString()),
                        LogoTextTb.FontSize, LogoTextTb.Foreground));
            }
        }

        protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
        {
            base.OnRenderSizeChanged(sizeInfo);
            mWidth = sizeInfo.NewSize.Width;
            mHeight = sizeInfo.NewSize.Height;

            InitLogoCoordinate();
        }
        #region Init
        private void InitLogoCoordinate()
        {
            double centerY = mHeight / 2f - LogoTextTb.ActualHeight / 2;
            double textWidth = LogoTextTb.ActualWidth;
            double fontSize = LogoTextTb.FontSize;
            string fontFamily = LogoTextTb.FontFamily.ToString();

            double startX = (mWidth - textWidth) / 2;
            aimLocationPoints.Clear();
            randomLocationPoints.Clear();
            // 记录 原始坐标
            for (int i = 0; i < LogoTexts.Length; i++)
            {
                string str = LogoTexts[i].ToString();
                double currentWidth = MeasureTextWidth(str, fontSize, fontFamily);
                aimLocationPoints.Add(new Point(startX, centerY));
                startX += currentWidth;
            }

            Random random = new Random();
            // 产生 随机坐标
            for (int i = 0; i < LogoTexts.Length; i++)
            {
                randomLocationPoints.Add(new Point(random.NextDouble() * mWidth, random.NextDouble() * mHeight));
            }
        }
        #endregion
        /// <summary>
        /// 
        /// </summary>
        /// <param name="drawingContext"></param>
        protected override void OnRender(DrawingContext drawingContext)
        {
            if (randomLocationPoints.Count > 0 && aimLocationPoints.Count > 0 && randomLocationPoints.Count == aimLocationPoints.Count)
            {
                // 画移动的文字。移动结束后，就不画了。
                for (int i = 0; i < LogoTextFormatteds.Count; i++)
                {
                    if (isMoving)
                    {
                        double x = randomLocationPoints[i].X + percent * (aimLocationPoints[i].X - randomLocationPoints[i].X);
                        double y = randomLocationPoints[i].Y + percent * (aimLocationPoints[i].Y - randomLocationPoints[i].Y);
                        drawingContext.DrawText(LogoTextFormatteds[i], new Point(x, y));
                    }
                }
            }
        }
        /// <summary>
        /// 测量一个文字的宽度
        /// </summary>
        /// <param name="text"></param>
        /// <param name="fontSize"></param>
        /// <param name="fontFamily"></param>
        /// <returns></returns>
        private double MeasureTextWidth(string text, double fontSize, string fontFamily)
        {
            FormattedText formattedText = new FormattedText(
                text,
                System.Globalization.CultureInfo.InvariantCulture,
                FlowDirection.LeftToRight,
                new Typeface(fontFamily),
                fontSize,
                Brushes.Black
            );
            return formattedText.WidthIncludingTrailingWhitespace;
        }

        private void Start()
        {
            isMoving = true;
            InitTimer();
        }

        #region 渐变的 Brush
        LinearGradientBrush linearBrush;
        private void InitLinearBrush()
        {
            // 首尾用最初的color，是为了保证 光晕打过去的效果
            Color textColor = ((SolidColorBrush)LogoTextTb.Foreground).Color;
            GradientStopCollection gradientStops = new GradientStopCollection();
            gradientStops.Add(new GradientStop(textColor, 0.0));
            gradientStops.Add(new GradientStop(Colors.Red, 0.10));
            gradientStops.Add(new GradientStop(Colors.Orange, 0.45));
            gradientStops.Add(new GradientStop(Colors.Pink, 0.75));
            gradientStops.Add(new GradientStop(Colors.Yellow, 0.95));
            gradientStops.Add(new GradientStop(textColor, 1));
            linearBrush = new LinearGradientBrush(gradientStops, 0.0);
            linearBrush.StartPoint = new Point(0, 0);
            linearBrush.EndPoint = new Point(1, 1);

            TranslateTransform transfrom = new TranslateTransform();
            RegisterName(NAME_TRANSFORM, transfrom);
            linearBrush.Transform = transfrom;
        }

        private void InitGradientAnim()
        {
            // 设置背景色
            LogoTextTb.Foreground = linearBrush;
            // 动画
            DoubleAnimation anim = new DoubleAnimation();
            anim.From = -mWidth / 2;
            anim.To = mWidth / 2;
            anim.RepeatBehavior = RepeatBehavior.Forever;
            anim.Duration = new Duration(TimeSpan.FromSeconds(TIME_FOREGROUND_TRANSFORM));

            Storyboard myStoryboard = new Storyboard();
            // 设置动画对象
            Storyboard.SetTargetName(anim, NAME_TRANSFORM);
            // 设置动画对象属性
            Storyboard.SetTargetProperty(anim, new PropertyPath(TranslateTransform.XProperty));
            myStoryboard.Children.Add(anim);
            myStoryboard.Begin(LogoTextTb);
        }

        #endregion

        #region 定时器
        Timer timer = new Timer();
        double percent = 0.0;
        private void InitTimer()
        {
            // 20ms一帧
            timer.Interval = 20;
            timer.Elapsed += timer_Elapsed;
            timer.Start();
        }

        void timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (!isMoving)
                return;
            this.Dispatcher.Invoke(() =>
            {
                percent += 0.03;
                if (percent >= 1)
                {
                    percent = 1;
                    isMoving = false;
                    StopTimer();
                    LogoTextTb.Visibility = Visibility.Visible;
                    InitGradientAnim();
                }
                this.InvalidateVisual();
            });
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            Start();
        }

        private void StopTimer()
        {
            timer.Stop();
        }
        #endregion
    }
}
